using System;
using System.Dynamic;

namespace Agile.DataAccess
{
    /// <summary>
    /// 
    /// </summary>
    public interface IDbContext : IDisposable
    {
        /// <summary>
        /// 
        /// </summary>
        DbContextData Data { get; }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ignoreIfAutoMapFails"></param>
        /// <returns></returns>
        IDbContext IgnoreIfAutoMapFails(bool ignoreIfAutoMapFails);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="useTransaction"></param>
        /// <returns></returns>
        IDbContext UseTransaction(bool useTransaction);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="useSharedConnection"></param>
        /// <returns></returns>
        IDbContext UseSharedConnection(bool useSharedConnection);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns></returns>
        IDbContext CommandTimeout(int timeout);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        IDbCommand Script(string sql, params object[] parameters);
        /// <summary>
        /// 
        /// </summary>
        IDbCommand MultiResultSql { get; }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IQueryBuilder<T> Builder<T>();
/// <summary>
/// 
/// </summary>
/// <param name="tableName"></param>
/// <returns></returns>
        ISelectBuilder Select(string tableName);
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tableName"></param>
        /// <returns></returns>
        ISelectBuilder<T> Select<T>(string tableName);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        IInsertBuilder Insert(string tableName);
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tableName"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        IInsertBuilder<T> Insert<T>(T item, string tableName );
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        IInsertBuilderDynamic Insert(string tableName, ExpandoObject item);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        IUpdateBuilder Update(string tableName);
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tableName"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        IUpdateBuilder<T> Update<T>(T item, string tableName);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        IUpdateBuilderDynamic Update(string tableName, ExpandoObject item);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        IDeleteBuilder Delete(string tableName);
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tableName"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        IDeleteBuilder<T> Delete<T>(T item, string tableName);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        IExistsBuilder Exists(string tableName);

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="item"></param>
        /// <param name="tableName"></param>
        /// <returns></returns>
        IExistsBuilder<T> Exists<T>(T item, string tableName);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="storedProcedureName"></param>
        /// <returns></returns>
        IStoredProcedureBuilder Procedure(string storedProcedureName);
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="storedProcedureName"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        IStoredProcedureBuilder<T> Procedure<T>(T item, string storedProcedureName);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="storedProcedureName"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        IStoredProcedureBuilderDynamic Procedure(string storedProcedureName, ExpandoObject item);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entityFactory"></param>
        /// <returns></returns>
        IDbContext EntityFactory(IEntityFactory entityFactory);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="fluentDataProvider"></param>
        /// <param name="providerName"></param>
        /// <returns></returns>
        IDbContext ConnectionString(string connectionString, IDbProvider fluentDataProvider, string providerName = null);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="fluentDataProvider"></param>
        /// <param name="adoNetProviderFactory"></param>
        /// <returns></returns>
        IDbContext ConnectionString(string connectionString, IDbProvider fluentDataProvider, System.Data.Common.DbProviderFactory adoNetProviderFactory);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="connectionstringName"></param>
        /// <param name="dbProvider"></param>
        /// <returns></returns>
        IDbContext ConnectionStringName(string connectionstringName, IDbProvider dbProvider);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="isolationLevel"></param>
        /// <returns></returns>
        IDbContext IsolationLevel(IsolationLevel isolationLevel);
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        IDbContext Commit();
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        IDbContext Rollback();
        /// <summary>
        /// 
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        IDbContext OnConnectionOpening(Action<ConnectionEventArgs> action);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        IDbContext OnConnectionOpened(Action<ConnectionEventArgs> action);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        IDbContext OnConnectionClosed(Action<ConnectionEventArgs> action);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        IDbContext OnExecuting(Action<CommandEventArgs> action);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        IDbContext OnExecuted(Action<CommandEventArgs> action);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="action"></param>
        /// <returns></returns>
        IDbContext OnError(Action<ErrorEventArgs> action);

    }
}